package com.enjoy.servlet3;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.http.HttpServletRequest;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * HTTp长连接
 * 基于ajax的长轮询 1、用到springMVC的异步处/2、或servelet3的一异步任务
 * 如果要采用异步处理，那么就要返回DeferedResult<>泛型对象。在调用完控制层之后，立即回返回DeferedResult对象，此时驱动控制层的容器主线程，可以处理更多的请求。
 可以将DeferedResult对象作为真实响应数据的代理，而真实的数据是该对象的成员变量result，它可以是String类型，或者ModelAndView类型等。
 业务处理完毕之后，要执行setResult方法，将真实的响应数据赋值到DeferedResult对象中。此时，容器主线程会继续执行getResult方法，
 将真实数据响应到客户端。
 * Created by HP on 2019/7/16.
 */
@Controller
@RequestMapping(produces = "text/html;charset=UTF-8")
public class PushNewsController {
    private ExecutorService executorService
            = Executors.newFixedThreadPool(1);

    @RequestMapping("/pushnews")
    public String news(){
        return "pushNews";
    }
    @RequestMapping(value="/realTimeNews")
    @ResponseBody
    /*在WebInitializer中要加上servlet.setAsyncSupported(true);*/
    public DeferredResult<String> realTimeNews(HttpServletRequest request){
        final DeferredResult<String> dr=new DeferredResult<String>();
        //交给线程池去处理 controller 可以继续处理客户新的请求
        executorService.submit(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int index = new Random().nextInt(Const.NEWS.length);
                //这边处理完后会返回给前端
                dr.setResult(Const.NEWS[index]);
                System.out.println("1111111111");
            }
        });
        System.out.println("**************");
        return dr;
    }
}
